package com.cema.manage.project.android.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.cema.manage.mail.MailService;
import com.cema.manage.project.android.model.AdCsjVo;
import com.cema.manage.project.android.service.BizAdCallbackService;
import com.cema.manage.project.enums.CallbackAdRecordEnum;
import com.cema.manage.project.enums.MoneyTypeEnum;
import com.cema.manage.project.enums.RedisEnum;
import com.cema.manage.project.enums.UserStatusEnum;
import com.cema.manage.project.manage.adRecord.domain.AdRecord;
import com.cema.manage.project.manage.adRecord.service.IAdRecordService;
import com.cema.manage.project.manage.rewardRecord.domain.RewardRecord;
import com.cema.manage.project.manage.rewardRecord.service.IRewardRecordService;
import com.cema.manage.project.manage.users.domain.Users;
import com.cema.manage.project.manage.users.service.IUsersService;
import com.cema.manage.redis.RedisService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class BizAdCallbackServiceImpl implements BizAdCallbackService {
    @Resource
    private IRewardRecordService rewardRecordService;

    @Resource
    private IAdRecordService adRecordService;

    @Resource
    private IUsersService usersService;

    @Resource
    private RedisService redisService;

    @Resource
    private MailService mailService;

    private final ReentrantLock lock = new ReentrantLock();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createRewardRecord(AdCsjVo adCsjVo) {
        lock.lock();
        try {
            Users users = usersService.selectById(adCsjVo.getUser_id());
            if (ObjectUtil.isNull(users)) {
                return false;
            }
            EntityWrapper<AdRecord> entityWrapper = new EntityWrapper<>();
            entityWrapper.eq("ar_trans_id", adCsjVo.getExtra());
            int count = adRecordService.selectCount(entityWrapper);
            if (count == 0) {
                return false;
            }
            //避免重复回调写入数据
            EntityWrapper<RewardRecord> recordEntityWrapper = new EntityWrapper<>();
            recordEntityWrapper.eq("rr_trans_id", adCsjVo.getExtra());
            int recordCount = rewardRecordService.selectCount(recordEntityWrapper);
            if (recordCount > 0) {
                return true;
            }
            //平台默认1：10000
            Double ecpm = Double.parseDouble(adCsjVo.getEcpm());
            //修改比例1：10000
            ecpm = ecpm / 10;
            //异常发送邮件
            String adEcpm = (String) redisService.get(RedisEnum.AD_ECPM.getKey()+adCsjVo.getUvChannel());
            if (StrUtil.isNotEmpty(adEcpm) && ecpm > Double.parseDouble(adEcpm)) {
                String name = (String) redisService.get(RedisEnum.APP_NAME.getKey());
                mailService.sendSimpleMail("异常通知", name + "【用户ID：" + users.getId() +
                        "】【用户名：" + users.getNickname() + "】【ECMP：" + ecpm + "】");
            }
            //分配给用户
            String allocationAd = (String) redisService.get(RedisEnum.ALLOCATION_AD.getKey()+adCsjVo.getUvChannel());
            Integer kik = StrUtil.isNotEmpty(allocationAd) ? Integer.parseInt(allocationAd) : 0;
            if (ObjectUtil.isNotNull(users.getKickback())) {
                kik = users.getKickback();
            }
            double kickback = kik / 100.0;
            ecpm = ecpm * kickback;
            //红包
            Integer moneyRedPacket = Integer.parseInt(redisService.get(RedisEnum.ALLOCATION_MONEY_RED_PACKET.getKey()+adCsjVo.getUvChannel()).toString());
            //金币
            Integer moneyGoldCoin = Integer.parseInt(redisService.get(RedisEnum.ALLOCATION_MONEY_GOLD_COIN.getKey()+adCsjVo.getUvChannel()).toString());
            Double species = ecpm * moneyGoldCoin / 100.0;
            Double redPacket = ecpm * moneyRedPacket / 100.0;
            Integer valueSpecies = species.intValue();
            Integer valueRedPacket = redPacket.intValue();
            if (moneyGoldCoin > 100) {
                valueSpecies = moneyGoldCoin;
            }
            if (moneyRedPacket > 100) {
                valueRedPacket = moneyRedPacket;
            }
            //生成记录
            List<RewardRecord> rewardRecordList = new ArrayList<>(3);
            //金币
            rewardRecordList.add(addRewardRecord(adCsjVo, users, valueSpecies, moneyGoldCoin, MoneyTypeEnum.MONEY_GOLD_COINS.getValue()));
            //红包
            rewardRecordList.add(addRewardRecord(adCsjVo, users, valueRedPacket, moneyRedPacket, MoneyTypeEnum.MONEY_RED_ENVELOPE.getValue()));
            //更新广告回调
            AdRecord adRecord = new AdRecord();
            if (ObjectUtil.isNotNull(users.getUsParentId()) && moneyRedPacket <= 100 && moneyGoldCoin <= 100) {
                //存在推荐人
                setUsParentMoney(rewardRecordList, adRecord, users.getUsParentId(), users.getId(), kik, adCsjVo);
            }
            //创建邀请人记录
            rewardRecordService.insertBatch(rewardRecordList);

            //更新用户
            Users userUpdate = new Users();
            int moneyGold = users.getMoneyGoldCoin() + valueSpecies;
            userUpdate.setMoneyGoldCoin(moneyGold);
            int moneyRed = users.getMoneyRedPacket() + valueRedPacket;
            userUpdate.setMoneyRedPacket(moneyRed);
            userUpdate.setId(users.getId());
            usersService.updateById(userUpdate);
            //更新缓存
            users.setMoneyGoldCoin(moneyGold);
            users.setMoneyRedPacket(moneyRed);
            redisService.set(users.getOpenid() + users.getDeviceId(), users);

            adRecord.setArCallback(CallbackAdRecordEnum.CALLBACK_YES.getValue());
            return adRecordService.update(adRecord, entityWrapper);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 推荐人金币
     *
     * @param rewardRecordList
     * @param adRecord
     * @param parentId
     * @param userId
     * @param userKickback
     * @param adCsjVo
     */
    private void setUsParentMoney(List<RewardRecord> rewardRecordList, AdRecord adRecord, Integer parentId, Integer userId, Integer userKickback, AdCsjVo adCsjVo) {
        Users parentUsers = usersService.selectById(parentId);
        if (ObjectUtil.isNull(parentUsers)) {
            return;
        }
        if (UserStatusEnum.USER_STATUS_VIOLATION.getValue().equals(parentUsers.getStatus())) {
            return;
        }
        Integer parentKickback = parentUsers.getKickback();
        if (ObjectUtil.isNull(parentKickback)) {
            return;
        }
        //分配给用户
        int currentKik = parentKickback - userKickback;
        if (currentKik <= 0) {
            return;
        }
        //平台默认1：1000
        Double ecpm = Double.parseDouble(adCsjVo.getEcpm());
        //修改比例1：10000
        ecpm = ecpm / 10;
        double kickback = currentKik / 100.0;
        ecpm = ecpm * kickback;
        //红包
        Integer moneyRedPacket = Integer.parseInt(redisService.get(RedisEnum.ALLOCATION_MONEY_RED_PACKET.getKey()+adCsjVo.getUvChannel()).toString());
        //金币
        Integer moneyGoldCoin = Integer.parseInt(redisService.get(RedisEnum.ALLOCATION_MONEY_GOLD_COIN.getKey()+adCsjVo.getUvChannel()).toString());
        Double species = ecpm * moneyGoldCoin / 100.0;
        Double redPacket = ecpm * moneyRedPacket / 100.0;
        Integer valueSpecies = species.intValue();
        Integer valueRedPacket = redPacket.intValue();
        //金币
        RewardRecord rewardRecord = addRewardRecord(adCsjVo, parentUsers, valueSpecies, moneyGoldCoin, MoneyTypeEnum.MONEY_COMMISSION_GOLD_COINS.getValue());
        rewardRecord.setPusId(userId);
        rewardRecordList.add(rewardRecord);
        //红包
        RewardRecord record = addRewardRecord(adCsjVo, parentUsers, valueRedPacket, moneyRedPacket, MoneyTypeEnum.MONEY_COMMISSION_RED_ENVELOPE.getValue());
        record.setPusId(userId);
        rewardRecordList.add(record);
        //更新用户
        Users userUpdate = new Users();
        int moneyCmmissionGoldCoin = parentUsers.getMoneyCommissionGoldCoin() + valueSpecies;
        userUpdate.setMoneyCommissionGoldCoin(moneyCmmissionGoldCoin);
        int moneyCommissionRedEnvelope = parentUsers.getMoneyCommissionRedEnvelope() + valueRedPacket;
        userUpdate.setMoneyCommissionRedEnvelope(moneyCommissionRedEnvelope);
        userUpdate.setId(parentUsers.getId());
        usersService.updateById(userUpdate);
        adRecord.setUsParentId(parentUsers.getId());
        adRecord.setUsParentMoney(ecpm.intValue());
        adRecord.setUsParentKickback(currentKik);
    }

    /**
     * 构建记录对象
     *
     * @param adCsjVo
     * @param users
     * @param valueSpecies
     * @param allocation
     * @param type
     * @return
     */
    private RewardRecord addRewardRecord(AdCsjVo adCsjVo, Users users, Integer valueSpecies, Integer allocation, Integer type) {
        RewardRecord rewardRecord = new RewardRecord();
        rewardRecord.setUsId(users.getId());
        rewardRecord.setUsNickname(users.getNickname());
        rewardRecord.setRrMoney(valueSpecies);
        rewardRecord.setRrType(type);
        rewardRecord.setRrSourceType(2);
        rewardRecord.setRrTransId(adCsjVo.getExtra());
        rewardRecord.setRrAllocation(allocation);
        //验证是否奖励邀请人
        return rewardRecord;
    }
}
